package com.handy.database;

import java.io.BufferedReader;
import java.io.Reader;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.sql.DataSource;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.handy.util.Toolkit;
import com.handy.webwork.config.HandyConfiguration;

/**
 * 通过jndi检索系统数据源.
 * 
 * @author rocken.zeng@gmail.com
 * 
 */
public class DBUtil { 
	
	/**
	 * 构造函数，并初始化默认的数据库名称(handy.properties文件中的datasource值)。
	 */
	private DBUtil() {
		setDataSourceName(HandyConfiguration
				.properties(HandyConfiguration.PROP_DATASOURCE));
	}
	
	/**
	 * 单例
	 * @return
	 */
	public static synchronized DBUtil getInstance() {
		if (instance == null) {
			instance = new DBUtil();
		}
		return instance;
	}
	
	/**
	 * 创建数据源JNDI。不使用容器的数据源可以自己来创建。
	 * @param dataSourceName 数据源名称 
	 * @param driverClassName 数据源驱动类名
	 * @param username 登录账号
	 * @param password 登录口令
	 * @param url 访问链接
	 */
	public void createJNDI(String dataSourceName, String driverClassName,
			String username, String password, String url) {
		System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
				"com.sun.jndi.fscontext.RefFSContextFactory");
		createJNDI(dataSourceName, driverClassName, username, password, url,
				10, 50, 5, 60);
	}

	/**
	 * 创建数据源JNDI。不使用容器的数据源可以自己来创建。
	 * @param dataSourceName 数据源名称 
	 * @param driverClassName 数据源驱动类名
	 * @param username 登录账号
	 * @param password 登录口令
	 * @param url 访问链接
	 * @param initialSize 初始连接数量
	 * @param maxActive 最大连接数量
	 * @param maxIdle 最大空闲连接
	 * @param maxWait 超时回收时间，单位秒
	 */
	public void createJNDI(String dataSourceName, String driverClassName,
			String username, String password, String url, int initialSize,
			int maxActive, int maxIdle, int maxWait) {
		System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
				"com.sun.jndi.fscontext.RefFSContextFactory");
		InitialContext ic;
		try {
			ic = new InitialContext();
			Reference ref = new Reference("javax.sql.DataSource",
					"org.apache.commons.dbcp.BasicDataSourceFactory", null);
			ref.add(new StringRefAddr("driverClassName", driverClassName));
			ref.add(new StringRefAddr("url", url));
			ref.add(new StringRefAddr("username", username));
			ref.add(new StringRefAddr("password", password));

			ref.add(new StringRefAddr("defaultInitialSize", String.valueOf(initialSize)));// 初始连接数量
			ref.add(new StringRefAddr("defaultMaxActive", String.valueOf(maxActive)));// 最大连接数量
			ref.add(new StringRefAddr("defaultMaxIdle", String.valueOf(maxIdle)));// 最大空闲连接
			ref.add(new StringRefAddr("defaultMaxWait", String.valueOf(maxWait*1000)));// 超时回收时间

			ic.rebind("java:comp/env/" + dataSourceName, ref);
		} catch (NamingException e) {
			log.error(e.getMessage());
		}
	}

	/**
	 * 检索指定名字的数据源.
	 * 
	 * @param dataSourceName 数据源名称 
	 * @return
	 */
	public DataSource dataSource(String dataSourceName) {
		if (dataSourceName == null || dataSourceName.equals("")) {
			return dataSource();
		} else {
			return findDataSource(dataSourceName);
		}
	}

	/**
	 * 取handy.properties中配置的数据源
	 * 
	 * @return
	 */
	public DataSource dataSource() {
		//当没有传入dataSourceName参数时分两种情况
		if (null != getDataSource()){
			return getDataSource();
		}
//		log.info("======================");
//		log.info(getDataSourceName());
		return findDataSource(getDataSourceName());
	}
	
	/**
	 * 取指定名称的数据源.<br>
	 * 
	 * @param dataSourceName
	 * @return
	 */
	private DataSource findDataSource(String dataSourceName) {
		DataSource ds = null;
		try {
			if (ds == null) {
				Context ic = new InitialContext();
				ds = (DataSource) ic.lookup("java:comp/env/" + dataSourceName);
			}
		} catch (NamingException e) {
			log.error(e.getMessage());
		}
		return ds;
	}

	/**
	 * 取handy.properties中配置的数据源中的数据库连接.
	 * 
	 * @return
	 */
	public Connection getConnection() {
		Connection conn = null;
		try {
			conn = dataSource().getConnection();
		} catch (SQLException e) {
			log.error(e.getMessage());
		}
		return conn;
	}

	/**
	 * 指定数据源名称取数据库连接.
	 * 
	 * @param dataSourceName 数据源名称 
	 * @return
	 */
	public Connection getConnection(String dataSourceName) {
		if (null == dataSourceName || "".equals(dataSourceName))
			return getConnection();
		Connection conn = null;
		try {
			conn = dataSource(dataSourceName).getConnection();
		} catch (SQLException e) {
			log.error(e.getMessage());
		}
		return conn;
	}

	
	///////////////////////////////////////////////////////////////////////////////////
	//以下是使用DbUtils操作数据库
	///////////////////////////////////////////////////////////////////////////////////
	
    /**  
     * 执行sql语句  
     * @param sql sql语句  
     * @return 受影响的行数  
     */  
    public int update(String dataSourceName,String sql) {   
        return update(dataSourceName,sql, null);   
    }
    
    /**  
     * 执行sql语句  
     * <code>  
     * executeUpdate("update user set username = 'kitty' where username = ?", "hello kitty");  
     * </code>  
     * @param sql sql语句  
     * @param param 参数  
     * @return 受影响的行数  
     */  
    public int update(String dataSourceName,String sql, Object param) {   
        return update(dataSourceName,sql, new Object[] { param });   
    }   
       
    /**  
     * 执行sql语句  
     * @param sql sql语句  
     * @param params 参数数组  
     * @return 受影响的行数  
     */  
    public int update(String dataSourceName, String sql, Object[] params) {   
    	QueryRunner run  = new QueryRunner(dataSource(dataSourceName));   
        int affectedRows = 0;   
        try {   
            if (params == null) {   
                affectedRows = run.update(sql);   
            } else {   
                affectedRows = run.update(sql, params);   
            }   
        } catch (SQLException e) {   
            log.error(e.getMessage());   
        }   
        return affectedRows;   
    }   
    
    public int updateAndFindMaxID(String dataSourceName,String tableName,String sql) {   
        return updateAndFindMaxID(dataSourceName,tableName,sql, null);   
    }
    
    public int updateAndFindMaxID(String dataSourceName,String tableName,String sql, Object param) {   
        return updateAndFindMaxID(dataSourceName,tableName,sql, new Object[] { param });   
    }   
    
    /**
     * 
     * @param dataSourceName
     * @param tableName
     * @param sql
     * @param params
     * @return 指定表的最大id值。
     */
    public int updateAndFindMaxID(String dataSourceName,String tableName, String sql, Object[] params) {   
    	QueryRunner run  = new QueryRunner(dataSource(dataSourceName));   
        int affectedRows = 0;
        int id=0;
        try {
        	synchronized(MARK){
        		if (params == null) {   
                    affectedRows = run.update(sql);   
//        			run.update(sql);
                } else {   
                    affectedRows = run.update(sql, params);   
//                	run.update(sql, params);
                }
        		//取最后一条记录的id号
        		if (affectedRows>0){
        			StringBuffer sb = new StringBuffer();
            		sb.append("select max(id) from ").append(tableName);
            		id = getSampleIntegerValue(dataSourceName,sb.toString());
        		}
        	}
        } catch (SQLException e) {   
            log.error(e.getMessage());   
        }   
        return id;   
    }   
    
    
    /**  
     * 执行批量sql语句  
     * @param sql sql语句  
     * @param params 二维参数数组  
     * @return 受影响的行数的数组  
     */  
    public int[] batchUpdate(String dataSourceName, String sql, Object[][] params) {   
    	QueryRunner run  = new QueryRunner(dataSource(dataSourceName));   
        int[] affectedRows = new int[0];   
        try {   
            affectedRows = run.batch(sql, params);   
        } catch (SQLException e) {   
            log.error("Error occured while attempting to batch update data", e);   
        }   
        return affectedRows;   
    }

    public int[] batchUpdate(String dataSourceName, String sql, String[] param, String spliteString) {
    	int[] affectedRows = new int[0];
    	
    	QueryRunner run  = new QueryRunner(dataSource(dataSourceName));
    	int len1 = param.length;
    	int len2 = param[0].split(spliteString).length;
    	Object[][] params = new Object[len2][len1];
    	//{{col1,col2,col3},{col1,col2,col3}}
    	int i=0;
        for (String _param:param){
            Object[] _params = _param.split(spliteString);
			for (int j = 0; j < _params.length; j++) {
				params[j][i] = _params[j];
			}
			i++;
        }
        
        try {   
            affectedRows = run.batch(sql, params);   
        } catch (SQLException e) {   
            log.error("Error occured while attempting to batch update data", e);   
        }   
        return affectedRows;   
    } 
    
    public int[] batchUpdate(String dataSourceName, String sql, String param, String spliteString) { 
    	String[] _param = { param }; 
        return batchUpdate(dataSourceName,sql,_param,spliteString);
    } 
  
    /**  
     * 执行查询，将每行的结果保存到一个Map对象中，然后将所有Map对象保存到List中  
     * @param sql sql语句  
     * @return 查询结果  
     */  
    public List<Map<String, Object>> find(String dataSourceName, String sql) {   
        return find(dataSourceName,sql, null);   
    }   
       
    /**  
     * 执行查询，将每行的结果保存到一个Map对象中，然后将所有Map对象保存到List中  
     * @param sql sql语句  
     * @param param 参数  
     * @return 查询结果  
     */  
    public List<Map<String, Object>> find(String dataSourceName, String sql, Object param) {   
        return find(dataSourceName,sql, new Object[] {param});   
    }   
       
    /**  
     * 执行查询，将每行的结果保存到一个Map对象中，然后将所有Map对象保存到List中  
     * @param sql sql语句  
     * @param params 参数数组  
     * @return 查询结果  
     */  
    @SuppressWarnings({ "unchecked", "deprecation" })   
    public List<Map<String, Object>> find(String dataSourceName, String sql, Object[] params) {   
    	QueryRunner run  = new QueryRunner(dataSource(dataSourceName)); 
        List<Map<String, Object>> list = new ArrayList<Map<String,Object>>(); 

        try {   
            if (params == null) {   
                list = (List<Map<String, Object>>) run.query(sql, new MapListHandler());   
            } else {   
                list = (List<Map<String, Object>>) run.query(sql, params ,new MapListHandler());   
            }   
        } catch (SQLException e) {   
            log.error("Error occured while attempting to query data", e);   
        }   
        return list;   
    }   
       
    /**  
     * 执行查询，将每行的结果保存到Bean中，然后将所有Bean保存到List中  
     * @param entityClass 类名  
     * @param sql sql语句  
     * @return 查询结果  
     */  
    public <T> List<T> find(Class<T> entityClass, String dataSourceName, String sql) {   
        return find(entityClass, dataSourceName, sql, null);   
    }   
       
    /**  
     * 执行查询，将每行的结果保存到Bean中，然后将所有Bean保存到List中  
     * @param entityClass 类名  
     * @param sql sql语句  
     * @param param 参数  
     * @return 查询结果  
     */  
    public <T> List<T> find(Class<T> entityClass, String dataSourceName, String sql, Object param) {   
        return find(entityClass, dataSourceName, sql, new Object[] { param });   
    }   
       
    /**  
     * 执行查询，将每行的结果保存到Bean中，然后将所有Bean保存到List中  
     * @param entityClass 类名  
     * @param sql sql语句  
     * @param params 参数数组  
     * @return 查询结果  
     */  
    @SuppressWarnings({ "unchecked", "deprecation" })   
    public <T> List<T> find(Class<T> entityClass, String dataSourceName, String sql, Object[] params) {   
    	QueryRunner run  = new QueryRunner(dataSource(dataSourceName)); 
        List<T> list = new ArrayList<T>();   
        try {   
            if (params == null) {   
                list = (List<T>) run.query(sql, new BeanListHandler(entityClass));   
            } else {   
                list = (List<T>) run.query(sql, params, new BeanListHandler(entityClass));   
            }   
        } catch (SQLException e) {   
            log.error("Error occured while attempting to query data", e);   
        }   
        return list;   
    }   
       
    /**  
     * 查询出结果集中的第一条记录，并封装成对象  
     * @param entityClass 类名  
     * @param sql sql语句  
     * @return 对象  
     */  
    public <T> T findFirst(Class<T> entityClass, String dataSourceName, String sql) {   
        return findFirst(entityClass, dataSourceName, sql, null);   
    }   
       
    /**  
     * 查询出结果集中的第一条记录，并封装成对象  
     * @param entityClass 类名  
     * @param sql sql语句  
     * @param param 参数  
     * @return 对象  
     */  
    public <T> T findFirst(Class<T> entityClass, String dataSourceName, String sql, Object param) {   
        return findFirst(entityClass, dataSourceName, sql, new Object[] { param });   
    }   
       
    /**  
     * 查询出结果集中的第一条记录，并封装成对象  
     * @param entityClass 类名  
     * @param sql sql语句  
     * @param params 参数数组  
     * @return 对象  
     */  
    @SuppressWarnings({ "unchecked", "deprecation" })   
    public <T> T findFirst(Class<T> entityClass, String dataSourceName, String sql, Object[] params) {   
    	QueryRunner run  = new QueryRunner(dataSource(dataSourceName)); 
        Object object = null;   
        try {   
            if (params == null) {   
                object = run.query(sql, new BeanHandler(entityClass));   
            } else {   
                object = run.query(sql, new BeanHandler(entityClass),params);   
            }   
        } catch (SQLException e) {   
            log.error("Error occured while attempting to query data", e);   
        }   
        return (T) object;   
    }   
       
    /**  
     * 查询出结果集中的第一条记录，并封装成Map对象  
     * @param sql sql语句  
     * @return 封装为Map的对象  
     */  
    public Map<String, Object> findFirst(String dataSourceName,String sql) {   
        return findFirst(dataSourceName, sql, null);
    }   
       
    /**  
     * 查询出结果集中的第一条记录，并封装成Map对象  
     * @param sql sql语句  
     * @param param 参数  
     * @return 封装为Map的对象  
     */  
    public Map<String, Object> findFirst(String dataSourceName,String sql, Object param) {   
        return findFirst(dataSourceName, sql, new Object[] { param });   
    }   
       
    /**  
     * 查询出结果集中的第一条记录，并封装成Map对象  
     * @param sql sql语句  
     * @param params 参数数组  
     * @return 封装为Map的对象  
     */  
    @SuppressWarnings({ "unchecked", "deprecation" })   
    public Map<String, Object> findFirst(String dataSourceName, String sql, Object[] params) {   
    	QueryRunner run  = new QueryRunner(dataSource(dataSourceName)); 
        Map<String, Object> map = null;   
        try {   
            if (params == null) {   
                map = (Map<String, Object>) run.query(sql, new MapHandler());   
            } else {   
                map = (Map<String, Object>) run.query(sql, params, new MapHandler());   
            }   
        } catch (SQLException e) {   
            log.error("Error occured while attempting to query data", e);   
        }   
        return map;   
    }   
       
    /**  
     * 查询某一条记录，并将指定列的数据转换为Object  
     * @param sql sql语句  
     * @param columnName 列名  
     * @return 结果对象  
     */  
    public Object findBy(String dataSourceName,String sql, String columnName) {   
        return findBy(dataSourceName,sql, columnName, null);   
    }   
       
    /**  
     * 查询某一条记录，并将指定列的数据转换为Object  
     * @param sql sql语句  
     * @param columnName 列名  
     * @param param 参数  
     * @return 结果对象  
     */  
    public Object findBy(String dataSourceName,String sql, String columnName, Object param) {   
        return findBy(dataSourceName,sql, columnName, new Object[] { param });   
    }   
       
    /**  
     * 查询某一条记录，并将指定列的数据转换为Object  
     * @param sql sql语句  
     * @param columnName 列名  
     * @param params 参数数组  
     * @return 结果对象  
     */  
    @SuppressWarnings("deprecation")
	public Object findBy(String dataSourceName,String sql, String columnName, Object[] params) {   
    	QueryRunner run  = new QueryRunner(dataSource(dataSourceName)); 
        Object object = null;   
        try {   
            if (params == null) {   
                object = run.query(sql, new ScalarHandler(columnName));   
            } else {   
                object = run.query(sql, params, new ScalarHandler(columnName));   
            }   
        } catch (SQLException e) {   
            log.error("Error occured while attempting to query data", e);   
        }   
        return object;   
    }   
       
    /**  
     * 查询某一条记录，并将指定列的数据转换为Object  
     * @param sql sql语句  
     * @param columnIndex 列索引  
     * @return 结果对象  
     */  
    public Object findBy(String dataSourceName,String sql, int columnIndex) {   
        return findBy(dataSourceName,sql, columnIndex, null);   
    }   
       
    /**  
     * 查询某一条记录，并将指定列的数据转换为Object  
     * @param sql sql语句  
     * @param columnIndex 列索引  
     * @param param 参数  
     * @return 结果对象  
     */  
    public Object findBy(String dataSourceName,String sql, int columnIndex, Object param) {   
        return findBy(dataSourceName,sql, columnIndex, new Object[] { param });   
    }   
       
    /**  
     * 查询某一条记录，并将指定列的数据转换为Object  
     * @param sql sql语句  
     * @param columnIndex 列索引  
     * @param params 参数数组  
     * @return 结果对象  
     */  
    @SuppressWarnings("deprecation")
	public Object findBy(String dataSourceName,String sql, int columnIndex, Object[] params) {   
    	QueryRunner run  = new QueryRunner(dataSource(dataSourceName)); 
        Object object = null;   
        try {   
            if (params == null) {   
                object = run.query(sql, new ScalarHandler(columnIndex));   
            } else {   
                object = run.query(sql, new ScalarHandler(columnIndex), params);   
            }   
        } catch (SQLException e) {   
            log.error("Error occured while attempting to query data", e);   
        }   
        return object;   
    }   
	
    /**  
     * 查询指定列的数据转换为List<Object>  
     * @param sql sql语句  
     * @param columnIndex 列索引  
     * @param params 参数数组  
     * @return 结果对象  
     */  
    @SuppressWarnings("deprecation")
	public List<Object> findColumnBy(String dataSourceName,String sql, int columnIndex, Object[] params) {   
    	QueryRunner run  = new QueryRunner(dataSource(dataSourceName)); 
    	List<Object> list = null;   
        try {   
            if (params == null) {   
            	list = run.query(sql, new ColumnListHandler(columnIndex));   
            } else {   
            	list = run.query(sql, new ColumnListHandler(columnIndex), params);   
            }   
        } catch (SQLException e) {   
            log.error("Error occured while attempting to query data", e);   
        }   
        return list;   
    }
    
    /**  
     * 查询指定列的数据转换为List<Object>  
     * @param sql sql语句  
     * @param columnIndex 列索引  
     * @param params 参数数组  
     * @return 结果对象  
     */  
    @SuppressWarnings("deprecation")
	public List<Object> findColumnBy(String dataSourceName,String sql, String column, Object[] params) {   
    	QueryRunner run  = new QueryRunner(dataSource(dataSourceName)); 
    	List<Object> list = null;  
    	
        try {   
            if (params == null) {   
            	list = run.query(sql, new ColumnListHandler(column));   
            } else {   
            	list = run.query(sql, new ColumnListHandler(column), params);   
            }   
        } catch (SQLException e) {   
            log.error("Error occured while attempting to query data", e);   
        }   
        return list;   
    }
    
 
    
	///////////////////////////////////////////////////////////////////////////////////
	//以下是使用jdbc操作数据库
	///////////////////////////////////////////////////////////////////////////////////
	/**
	 * 通过默认数据源使用Statement方式执行非查询的sql语句。
	 * 
	 * @param mysql 将要执行的sql语句
	 * @return 执行成功返回true，否则返回false
	 */
	public boolean execute(String mysql) {
		return execute(null, mysql);
	}

	/**
	 * 使用Statement方式执行非查询的sql语句。
	 * 
	 * @param dataSourceName 数据源名称  
	 * @param 将要执行的sql语句
	 * @return 执行成功返回true，否则返回false
	 */
	public boolean execute(String dataSourceName, String mysql) {
		boolean _res = false;
		Statement stmt = null;
		Connection conn = null;
		try {
			conn = getConnection(dataSourceName);
			stmt = conn.createStatement();
			_res = stmt.execute(mysql);
		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			try {
				if (stmt != null)
					stmt.close();
				if (conn != null)
					conn.close();
			} catch (Exception e) {
				log.error(e.getMessage());
			}
		}
		return _res;
	}


	/**
	 * 通过默认数据源使用PreparedStatement方式执行非查询的sql语句。
	 * @param mysql 将要执行的sql语句
	 * @param param 一个Object值,将要传入sql的参数值。
	 * @return 执行成功返回true，否则返回false
	 */
	public boolean execute(String mysql,
			Object param) {
		return execute("",mysql,param);
	}
	
	/**
	 * 使用PreparedStatement方式执行非查询的sql语句。
	 * @param dataSourceName 数据源名称  
	 * @param mysql 将要执行的sql语句
	 * @param param 一个Object值,将要传入sql的参数值。
	 * @return 执行成功返回true，否则返回false
	 */
	public boolean execute(String dataSourceName, String mysql,
			Object param) {
		LinkedList<Object> params = new LinkedList<Object>();
		params.add(param);
		return execute(dataSourceName,mysql,params);
	}
	
	/**
	 * 通过默认数据源使用PreparedStatement方式执行非查询的sql语句。
	 * @param mysql 将要执行的sql语句
	 * @param params LinkedList<Object>,将要传入sql的参数值。
	 * @return 执行成功返回true，否则返回false
	 */
	public boolean execute(String mysql, LinkedList<Object> params) {
		return execute("", mysql, params);
	}
	
	/**
	 * 使用PreparedStatement方式执行非查询的sql语句。
	 * @param dataSourceName 数据源名称  
	 * @param mysql 将要执行的sql语句
	 * @param params LinkedList<Object>,将要传入sql的参数值。
	 * @return 执行成功返回true，否则返回false
	 */
	public boolean execute(String dataSourceName, String mysql,
			LinkedList<Object> params) {
		if (log.isDebugEnabled()){
			log.debug("使用PreparedStatement方式执行非查询的sql语句");
		}
		boolean _res = false;
		PreparedStatement pstmt = null;
		Connection conn = null;
		try {
			conn = getConnection(dataSourceName);
			pstmt = conn.prepareStatement(mysql);
			if (params != null) {
				int i = 1;
				for (java.util.Iterator<Object> iter = params.iterator();iter.hasNext();i++){
					Object _value = iter.next();
					if (_value instanceof String){
						pstmt.setString(i, (String)_value);
					}else if (_value instanceof Integer){
						pstmt.setInt(i, ((Integer)_value).intValue());
					}
				}
			}
			_res = pstmt.execute();
		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			try {
				if (pstmt != null)
					pstmt.close();
				if (conn != null)
					conn.close();
			} catch (Exception e) {
				log.error(e.getMessage());
			}
		}
		return _res;
	}

	/**
	 * 通过默认数据源使用Statement方式执行查询语句。
	 * @param sql 将要执行的sql语句
	 * @param cols 要查询的字段数
	 * @param lobs clob,blob字段所处位置，创建一个int[cols]数据，值为1则为clob,blob字段。
	 * @return
	 */
	public ArrayList<String[]> getRsToObjList(String sql, int cols,
			int[] lobs) {
		return getRsToObjList(null, sql, cols, lobs);
	}

	/**
	 * 使用Statement方式执行查询语句。
	 * @param dataSourceName 数据源名称  
	 * @param sql 将要执行的sql语句
	 * @param cols 要查询的字段数
	 * @param lobs clob,blob字段所处位置，创建一个int[cols]数据，值为1则为clob,blob字段。
	 * @return
	 */
	public ArrayList<String[]> getRsToObjList(String dataSourceName,
			String sql, int cols, int[] lobs) {
		ArrayList<String[]> list = new ArrayList<String[]>();
		Statement stmt = null;
		ResultSet rs = null;
		Connection conn = null;
		try {
			conn = getConnection(dataSourceName);

			stmt = conn.createStatement();
			rs = stmt.executeQuery(sql);
			// 取记录
			while (rs.next()) {
				String[] _temp = new String[cols];
				for (int i = 0; i < cols; i++) {
					if (lobs[i] == 0) {
						_temp[i] = rs.getString(i + 1);
					} else if (lobs[i] == 1) {// 如果该字段为clob类型
						Clob clob = rs.getClob(i + 1);
						_temp[i] = readClob(clob);
					}
				}
				list.add(_temp);
			}
		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (stmt != null)
					stmt.close();
				if (conn != null)
					conn.close();
			} catch (Exception e) {
				log.error(e.getMessage());
			}
		}
		return list;
	}

	public ArrayList<String[]> getRsToObjList(String dataSourceName,
			String sql, int cols, int[] lobs,Object param) {
		LinkedList<Object> params = new LinkedList<Object>();
		params.add(param);
		return getRsToObjList(dataSourceName,sql,cols,lobs,params);
	}
	
	/**
	 * 使用PreparedStatement方式执行查询语句。
	 * @param dataSourceName 数据源名称  
	 * @param sql 将要执行的sql语句
	 * @param cols 要查询的字段数
	 * @param lobs clob,blob字段所处位置，创建一个int[cols]数据，值为1则为clob,blob字段。
	 * @param params LinkedList<Object>,将要传入sql的参数值。
	 * @return
	 */
	public ArrayList<String[]> getRsToObjList(String dataSourceName,
			String sql, int cols, int[] lobs,LinkedList<Object> params) {
		if (log.isDebugEnabled()){
			log.debug("使用PreparedStatement方式执行查询语句");
		}
		ArrayList<String[]> list = new ArrayList<String[]>();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		Connection conn = null;
		try {
			conn = getConnection(dataSourceName);

			pstmt = conn.prepareStatement(sql);
			if (params != null) {
				int i = 1;
				for (java.util.Iterator<Object> iter = params.iterator();iter.hasNext();i++){
					Object _value = iter.next();
					if (_value instanceof String){
						pstmt.setString(i, (String)_value);
					}else if (_value instanceof Integer){
						pstmt.setInt(i, ((Integer)_value).intValue());
					}
				}
			}
			rs = pstmt.executeQuery();
			// 取记录
			while (rs.next()) {
				String[] _temp = new String[cols];
				for (int i = 0; i < cols; i++) {
					if (lobs[i] == 0) {
						_temp[i] = rs.getString(i + 1);
					} else if (lobs[i] == 1) {// 如果该字段为clob类型
						Clob clob = rs.getClob(i + 1);
						_temp[i] = readClob(clob);
					}
				}
				list.add(_temp);
			}
		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (pstmt != null)
					pstmt.close();
				if (conn != null)
					conn.close();
			} catch (Exception e) {
				log.error(e.getMessage());
			}
		}
		return list;
	}
	
	public String getSampleStringValue(String sql){
		return getSampleStringValue(null,sql);
	}
	
	public String getSampleStringValue(String dataSourceName,String sql){
		String ret = "";
		int cols=1;
		int[] lobs = {0};
		ArrayList<String[]> _temp = getRsToObjList(dataSourceName, sql, cols, lobs);
		if (!_temp.isEmpty()){
			ret = _temp.get(0)[0];
		}
		return ret;
	}
	
	public Integer getSampleIntegerValue(String sql){
		return getSampleIntegerValue(null,sql);
	}
	
	public Integer getSampleIntegerValue(String dataSourceName,String sql){
		String str = getSampleStringValue(dataSourceName,sql);
		if (Toolkit.isNumeric(str)){
			return Integer.valueOf(str);
		}
		return 0;
	}
	
	/**
	 * 读取Clob字段值到字串。
	 * 
	 * @param oclob
	 * @return
	 */
	private static String readClob(Clob oclob) {
		String str = "";
		try {
			if (oclob != null) {
				Reader is = oclob.getCharacterStream();
				BufferedReader br = new BufferedReader(is);
				StringBuffer ct = new StringBuffer();
				String s = "";
				while ((s = br.readLine()) != null) {
					ct.append(s);
				}
				str = ct.toString();
				is.close();
			}
		} catch (Exception ex) {
			log.error("readClob():" + ex.getMessage());
		}
		return str;
	}

	private static Log log = LogFactory.getLog(DBUtil.class);

	private static DBUtil instance = null;
	
	/**
	 * 默认数据源名称
	 */
	private String _dataSourceName = "";	
	
	private DataSource dataSource;
	
	public String getDataSourceName() {
		return _dataSourceName;
	}

	public void setDataSourceName(String dataSourceName) {
		this._dataSourceName = dataSourceName;
	}
	
	public DataSource getDataSource() {
		return dataSource;
	}

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}
	
	private static final byte[] MARK = new byte[0];
	
	/**
	 * Oracle8/8i/9iO数据库(thin模式)
	 */
	public static final String DB_DRIVER_ORACLE = "oracle.jdbc.driver.OracleDriver";
	public static final int DB_KIND_ORACLE = 1;
	
	/**
	 * Sql Server7.0/2000数据库 
	 */
	public static final String DB_DRIVER_SQLSERVER = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
	public static final int DB_KIND_SQLSERVER = 2;
	
	/**
	 * DB2数据库 
	 */
	public static final String DB_DRIVER_DB2 = "com.ibm.db2.jdbc.app.DB2Driver";
	public static final int DB_KIND_DB2 = 3;
	
	/**
	 * Informix数据库 
	 */
	public static final String DB_DRIVER_INFORMIX = "com.informix.jdbc.IfxDriver";
	public static final int DB_KIND_INFORMIX = 4;
	
	/**
	 * Sybase数据库 
	 */
	public static final String DB_DRIVER_SYBASE = "com.sybase.jdbc.SybDriver";
	public static final int DB_KIND_SYBASE = 5;
	
	/**
	 * MySQL数据库 
	 */
	public static final String DB_DRIVER_MYSQL = "com.mysql.jdbc.Driver";
	public static final int DB_KIND_MYSQL = 6;
	
	/**
	 * PostgreSQL数据库 
	 */
	public static final String DB_DRIVER_POSTGRESQL = "org.postgresql.Driver";
	public static final int DB_KIND_POSTGRESQL = 7;
	

}